package cn.sea;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * Created by DragonSea
 * on 2018-11-02
 */

/**
 * 处理上传数据
 */
public class UploadServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List types = Arrays.asList(".jpg", ".gif", ".avi", ".txt",".xls");
        try {
            //创建解析工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(1024 * 1024);
            //System.out.println(this.getServletContext().getRealPath(""));
            //factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
            //创建解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setHeaderEncoding("UTF-8");
            upload.setFileSizeMax(1024 * 1024 * 6); //上传文件不超过5M
            //调用解析器解析request,得到保存了所有上传数据的list
            List<FileItem> list = upload.parseRequest(request);
            //迭代list集合，拿到封装了每个输入项数据的fileItem
            for (FileItem fileItem : list) {
                //判断item的类型，如果是普通字段，则直接获取数据，如果为上传文件，则调用流获取数据写到本地
                if (fileItem.isFormField()) {
                    String inputName = fileItem.getFieldName();
                    String inputValue = fileItem.getString("UTF-8");
                    System.out.println(inputName + "=" + inputValue);
                } else {
                    String filename = fileItem.getName().substring(fileItem.getName().lastIndexOf("\\") + 1);
                    if(filename==null|| filename.trim().equals("")){
                        continue;
                    }
                    String ext = filename.substring(filename.lastIndexOf("."));
                    if (!types.contains(ext)) {
                        request.setAttribute("message", "本系统不支持" + ext + "格式！");
                        request.getRequestDispatcher("/index.jsp").forward(request, response);
                        return;
                    }

                    InputStream in = fileItem.getInputStream();
                    int len = 0;
                    byte[] buffer = new byte[1024];
                    String saveFileName=generateFileName(filename);
                    String savePath=generateSavePath(this.getServletContext().getRealPath("/upload"),saveFileName);
                    FileOutputStream out = new FileOutputStream(savePath+ File.separator+saveFileName);
                    while ((len = in.read(buffer)) > 0) {
                        out.write(buffer, 0, len);
                    }
                    out.close();
                    in.close();
                    fileItem.delete();
                }
            }
        }catch (FileUploadBase.FileSizeLimitExceededException e) {
            request.setAttribute("message", "文件不能超过6M");
            request.getRequestDispatcher("/index.jsp").forward(request,response);
        }catch (FileUploadException e) {
            e.printStackTrace();
        }
        request.setAttribute("message", "文件上传成功！");
        request.getRequestDispatcher("/index.jsp").forward(request,response);
    }
    //目录打散算法
    public String generateSavePath(String path,String fileName){
        int hashcode=fileName.hashCode();
        int dir1=hashcode&0xf;
        int dir2=(hashcode>>4)&0xf;
        String savePath=path+File.separator+dir1+File.separator+dir2;
        File file=new File(savePath);
        if(!file.exists()){
            file.mkdirs();
        }
        return savePath;

    }
    //生成唯一的文件名
    public String  generateFileName(String filename){
        return UUID.randomUUID().toString()+"_"+filename;
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}
